<template>
	<view>
		<view class="">
			<u-image :src="mask" :width="width+'px'" :height="height+'px'" error-icon="" loading-icon=""></u-image>
		</view>
		<view class="" id='mask' style="display: none;"></view>
	</view>
</template>

<script module="ctx" lang="renderjs">
	import fabirc from 'fabric'
	export default {
		name: "phone-case-mask",
		props: {
			width: {
				type: Number,
				default: 0,
			},
			height: {
				type: Number,
				default: 0,
			},
			phoneCaseId: {
				type: String,
				default: '',
			},
		},
		data() {
			return {
				mask:'',
				canvas: '',
				case: {
					x: 0,
					y: 0,
					width: 0,
					height: 0,
				},
			};
		},
		mounted() {
			this.init();
		},
		watch: {
			phoneCaseId: {
				immediate: true,
				handler(newVal, oldVal) {
					if (newVal != oldVal) {
						this.$nextTick(() => {
							let data = {
								_id: '001',
								name: '苹果 iPhone XS Max',
								width: 77.4,
								height: 157.5,
								radius: 2,
								holes: [{
										shape: 'square',
										x: 1.5,
										y: 1.5,
										width: 3,
										height: 8,
										radius: 1.5,
									},
									// {
									// 	shape: 'circle',
									// 	x: 1.2,
									// 	y: 1.2,
									// 	radius: 1.2,
									// },
									// {
									// 	shape: 'triangle',
									// 	x: 1.2,
									// 	y: 1.2,
									// 	width: 10,
									// 	radius: 1,
									// },
								]
							}
							this.draw(data)
						})
					}
				}
			}
		},
		methods: {
			init() {
				
			},
			
			/**
			 * 绘制
			 */
			draw(data) {
				//生成画布
				this._createCanvas();
				
				//宽高比
				data.aspectRatio = data.width / data.height;
				
				//组合
				let group = [];
				
				//边框
				group.push(this._drawBorder(data));
			
				//洞，摄像头，指纹等
				data.holes.map(hole => {
					hole.aspectRatio = data.aspectRatio;
					group.push(this._drawHole(hole));
				})
				
				//起始点坐标
				let scale = 0.88;
				this.case.width = this.canvas.height * data.aspectRatio * scale;
				this.case.height = this.canvas.height * scale;
				this.case.x = (this.canvas.width - this.case.width) / 2;
				this.case.y = (this.canvas.height - this.case.height) / 2;
				this.case.y = 15;
				
				let fabricGroup = new fabric.Group(group, {
					left: this.case.x,
					top: this.case.y,
					scaleX: scale,
					scaleY: scale,
					selectable: false,
					evented: false,
				})
				this.canvas.add(fabricGroup);
				
				//绘制空白
				this._drawBlank(data);
				
				this.mask = this.canvas.toDataURL();
			},
			
			//生成画布
			_createCanvas(){
				let container = document.getElementById('mask');
				let canvas = document.createElement('canvas');
				canvas.setAttribute("id", "mask_canvas");
				container.appendChild(canvas);
				
				//初始化
				this.canvas = new fabric.Canvas('canvas', {
					preserveObjectStacking: true,
				});
				
				//设置宽高
				this.canvas.setWidth(this.width);
				this.canvas.setHeight(this.height);
				this.canvas.renderAll();
			},
			
			/**
			 * 绘制手机壳边框
			 */
			_drawBorder(data) {
				//手机壳外边框
				let border = new fabric.Rect({
					left: 0,
					top: 0,
					width: this.height * data.aspectRatio - 2,
					height: this.height - 2,
					rx: vk.myfn.cmToPx(data.radius) * data.aspectRatio,
					ry: vk.myfn.cmToPx(data.radius) * data.aspectRatio,
				
					fill: 'transparent',
					stroke: '#000000',
					strokeWidth: 2,
					opacity: 0.9,
					strokeDashArray: [5, 5],
					selectable: false,
				})
				return border;
			},
			
			/**
			 * 绘制手机壳摄像头，指纹
			 */
			_drawHole(data) {
				if (data.shape == 'square') {
					let square = new fabric.Rect({
						left: vk.myfn.cmToPx(data.x) * data.aspectRatio,
						top: vk.myfn.cmToPx(data.y) * data.aspectRatio,
						width: vk.myfn.cmToPx(data.width) * data.aspectRatio,
						height: vk.myfn.cmToPx(data.height) * data.aspectRatio,
						ry: vk.myfn.cmToPx(data.radius) * data.aspectRatio,
				
						fill: 'rgba(245, 245, 245, 0.9)',
						stroke: '#000000',
						strokeWidth: 2,
						opacity: 0.9,
						strokeDashArray: [5, 5],
						selectable: false,
					})
					return square;
				}
				if (data.shape == 'circle') {
					let circle = new fabric.Circle({
						left: vk.myfn.cmToPx(data.x) * data.aspectRatio,
						top: vk.myfn.cmToPx(data.y) * data.aspectRatio,
						radius: vk.myfn.cmToPx(data.radius) * data.aspectRatio,
				
						fill: 'rgba(245, 245, 245, 0.9)',
						stroke: '#000000',
						strokeWidth: 2,
						opacity: 0.9,
						strokeDashArray: [5, 5],
						selectable: false,
					})
					return circle;
				}
				if (data.shape == 'triangle') {
					let n = vk.myfn.cmToPx(data.width) * data.aspectRatio;
					let r = vk.myfn.cmToPx(data.radius) * data.aspectRatio;
					let paths = [];
					paths.push(`M 0 ${r/Math.tan(30*Math.PI/180)}`);
					paths.push(`L 0 ${n-r/Math.tan(30*Math.PI/180)}`);
					paths.push(
						`Q 0 ${n} ${r/Math.tan(30*Math.PI/180)*Math.sin(60*Math.PI/180)} ${n-r/Math.tan(30*Math.PI/180)/2}`
					);
					paths.push(
						`L ${n*Math.sin(60*Math.PI/180)-r/Math.tan(30*Math.PI/180)*Math.sin(60*Math.PI/180)} ${n/2+r/Math.tan(30*Math.PI/180)/2}`
					);
					paths.push(
						`Q ${n*Math.sin(60*Math.PI/180)} ${n/2} ${n*Math.sin(60*Math.PI/180)-r/Math.tan(30*Math.PI/180)*Math.sin(60*Math.PI/180)} ${n/2-r/Math.tan(30*Math.PI/180)/2}`
					);
					paths.push(
						`L ${r/Math.tan(30*Math.PI/180)*Math.sin(60*Math.PI/180)} ${r/Math.tan(30*Math.PI/180)/2}}`
					);
					paths.push(`Q ${startX} ${startY} ${startX} ${r/Math.tan(30*Math.PI/180)}`);
					paths.push("z");
					let triangle = new fabric.Path(paths.join(" "), {
						left: vk.myfn.cmToPx(data.x) * data.aspectRatio,
						top: vk.myfn.cmToPx(data.y) * data.aspectRatio,
				
						fill: 'rgba(245, 245, 245, 0.9)',
						stroke: '#000000',
						strokeWidth: 2,
						opacity: 0.9,
						strokeDashArray: [5, 5],
						selectable: false,
					})
					return triangle
				}
			},
			
			/**
			 * 绘制空白
			 */
			_drawBlank(data) {
				//左空白
				let leftBlank = new fabric.Rect({
					left: -1,
					top: -1,
					width: (this.width - this.case.width) / 2 + 1,
					height: this.height + 2,
				
					fill: 'rgba(245, 245, 245, 0.9)',
				})
				this.canvas.add(leftBlank);
				
				//右空白
				let rightBlank = new fabric.Rect({
					left: this.case.x + this.case.width - 1,
					top: -1,
					width: (this.width - this.case.width) / 2 + 1,
					height: this.height + 2,
				
					fill: 'rgba(245, 245, 245, 0.9)',
				})
				this.canvas.add(rightBlank);
				
				//上空白
				let topBlank = new fabric.Rect({
					left: this.case.x - 1,
					top: -1,
					width: this.case.width + 1,
					height: this.case.y + 1,
				
					fill: 'rgba(245, 245, 245, 0.9)',
				})
				this.canvas.add(topBlank);
				
				//下空白
				let bottomBlank = new fabric.Rect({
					left: this.case.x - 0.67,
					top: this.case.y + this.case.height - 1,
					width: this.case.width + 0.5,
					height: this.case.y + this.case.height + 1,
				
					fill: 'rgba(245, 245, 245, 0.9)',
				})
				this.canvas.add(bottomBlank);
				
				
				/* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */
				let k = 1 - 0.5522847498;
				let r = vk.myfn.cmToPx(data.radius) * data.aspectRatio * 2.4;
				
				//四个角
				let paths = [];
				//左上
				paths.push(`M ${this.case.x} ${this.case.y}`);
				paths.push(`L ${this.case.x + k * r} ${this.case.y}`);
				paths.push(`Q ${this.case.x} ${this.case.y} ${this.case.x} ${this.case.y + k * r}`);
				paths.push(`L ${this.case.x} ${this.case.y + k * r}`);
				//右上
				paths.push(`M ${this.case.x + this.case.width} ${this.case.y}`);
				paths.push(`L ${this.case.x + this.case.width - k * r} ${this.case.y}`);
				paths.push(`Q ${this.case.x + this.case.width} ${this.case.y} ${this.case.x + this.case.width} ${this.case.y + k * r}`);
				paths.push(`L ${this.case.x + this.case.width} ${this.case.y + k * r}`);
				//左下
				paths.push(`M ${this.case.x} ${this.case.y + this.case.height}`);
				paths.push(`L ${this.case.x + k * r} ${this.case.y + this.case.height}`);
				paths.push(`Q ${this.case.x} ${this.case.y + this.case.height} ${this.case.x} ${this.case.y + this.case.height - k * r}`);
				paths.push(`L ${this.case.x} ${this.case.y + this.case.height + k * r}`);
				//右下
				paths.push(`M ${this.case.x + this.case.width} ${this.case.y + this.case.height}`);
				paths.push(`L ${this.case.x + this.case.width - k * r} ${this.case.y + this.case.height}`);
				paths.push(`Q ${this.case.x + this.case.width} ${this.case.y + this.case.height} ${this.case.x + this.case.width} ${this.case.y + this.case.height - k * r}`);
				paths.push(`L ${this.case.x + this.case.width} ${this.case.y + this.case.height - k * r}`);
				
				paths.push("z");
				let fillet = new fabric.Path(paths.join(" "), {
					fill: 'rgba(245, 245, 245, 0.9)',
				})
				this.canvas.add(fillet);
			},
		},
	}
</script>

<style>
</style>